<template>
  <div class="ant-pro-multi-tab">
    <div class="ant-pro-multi-tab-wrapper">
      <a-tabs
        v-model:activeKey="activeKey"
        hide-add
        type="editable-card"
        :tab-bar-style="{ margin: 0, paddingLeft: '16px', paddingTop: '1px' }"
        @edit="onEdit"
      >
        <a-tab-pane
          v-for="page in pages"
          :key="page.fullPath"
          :closable="pages.length > 1"
          style="height: 0"
        >
          <template #tab>
            <a-dropdown :trigger="['contextmenu']">
              <span :style="{ userSelect: 'none' }">
                <s-icon
                  v-if="page.meta && page.meta.icon && page.fullPath != activeKey"
                  :type="page.meta.icon"
                ></s-icon>
                <s-icon
                  v-if="page.fullPath == activeKey"
                  type="redo-outlined"
                  @click="$emit('refresh')"
                ></s-icon>
                {{ page.meta.customTitle || page.meta.title }}</span
              >
              <template #overlay>
                <a-menu
                  @click="
                    ({ key, item, domEvent }) => {
                      this.closeMenuClick(key, page.fullPath)
                    }
                  "
                >
                  <a-menu-item key="closeRight">
                    <s-icon type="vertical-left-outlined" />{{
                      $t('multiTab.closeRight')
                    }}</a-menu-item
                  >
                  <a-menu-item key="closeLeft"
                    ><s-icon type="vertical-right-outlined" />{{
                      $t('multiTab.closeLeft')
                    }}</a-menu-item
                  >
                  <a-menu-item key="closeOther"
                    ><s-icon type="close-outlined" />{{ $t('multiTab.closeOther') }}</a-menu-item
                  >
                </a-menu>
              </template>
            </a-dropdown>
          </template>
        </a-tab-pane>
      </a-tabs>
    </div>
  </div>
</template>
<script lang="ts">
import { defineComponent, ref, reactive, watch, getCurrentInstance } from 'vue'
import { useRouter, RouteLocationNormalizedLoaded } from 'vue-router'
import { message } from 'ant-design-vue'
import { useI18n } from 'vue-i18n'
import { currentApp, sidebarOpened } from '@/store/useSiteSettings'
import './index.less'

export default defineComponent({
  name: 'MultiTab',
  setup() {
    let fullPathList: Array<string> = []
    const pages = reactive<Array<RouteLocationNormalizedLoaded>>([])
    const activeKey = ref('')
    const router = useRouter()
    const { t } = useI18n()
    const { ctx } = getCurrentInstance()

    const selectedLastPath = () => {
      activeKey.value = fullPathList[fullPathList.length - 1]
    }

    ;(function created() {
      pages.push(router.currentRoute.value)
      fullPathList.push(router.currentRoute.value.fullPath)
      selectedLastPath()
    })()

    const remove = (targetKey) => {
      const temp = pages.filter((page) => page.fullPath !== targetKey)
      pages.length = 0
      pages.push(...temp)
      fullPathList = fullPathList.filter((path) => path !== targetKey)
      // 判断当前标签是否关闭，若关闭则跳转到最后一个还存在的标签页
      if (!fullPathList.includes(activeKey.value)) {
        selectedLastPath()
      }
    }

    // content menu
    const closeSelf = (e) => {
      // 判断是否为最后一个标签页，如果是最后一个，则无法被关闭
      if (fullPathList.length > 1) {
        remove(e)
      } else {
        message.info(t('multiTab.cannotCloseLast'))
      }
    }
    const closeLeft = (e) => {
      const currentIndex = fullPathList.indexOf(e)
      if (currentIndex > 0) {
        fullPathList.forEach((item, index) => {
          if (index < currentIndex) {
            remove(item)
          }
        })
      } else {
        message.info(t('multiTab.noLeft'))
      }
    }
    const closeRight = (e) => {
      const currentIndex = fullPathList.indexOf(e)
      if (currentIndex < fullPathList.length - 1) {
        fullPathList.forEach((item, index) => {
          if (index > currentIndex) {
            remove(item)
          }
        })
      } else {
        message.info(t('multiTab.noRight'))
      }
    }
    const closeOther = (e) => {
      const currentIndex = fullPathList.indexOf(e)
      fullPathList.forEach((item, index) => {
        if (index !== currentIndex) {
          remove(item)
        }
      })
    }
    const onEdit = (targetKey, action) => {
      switch (action) {
        case 'remove':
          remove(targetKey)
          break
        case 'closeSelf':
          closeSelf(targetKey)
          break
        case 'closeRight':
          closeRight(targetKey)
          break
        case 'closeLeft':
          closeLeft(targetKey)
          break
        case 'closeOther':
          closeOther(targetKey)
          break
      }
    }
    const closeMenuClick = (key: string, route) => {
      switch (key) {
        case 'closeSelf':
          closeSelf(route)
          break
        case 'closeRight':
          closeRight(route)
          break
        case 'closeLeft':
          closeLeft(route)
          break
        case 'closeOther':
          closeOther(route)
          break
      }
    }

    watch(
      () => router.currentRoute.value,
      (newVal) => {
        activeKey.value = newVal.fullPath
        if (fullPathList.indexOf(newVal.fullPath) < 0) {
          fullPathList.push(newVal.fullPath)
          pages.push(newVal)
        }
      }
    )
    watch(
      () => currentApp.value,
      (val) => {
        fullPathList.forEach((item, index) => {
          pages.length = 0
        })
      }
    )
    watch(activeKey, (newPathKey) => {
      router.push({ path: newPathKey })
    })

    return {
      fullPathList,
      pages,
      activeKey,
      onEdit,
      remove,
      selectedLastPath,
      closeSelf,
      closeLeft,
      closeRight,
      closeOther,
      closeMenuClick
    }
  }
})
</script>
<style lang="less">
.tab_style() {
  .ant-tabs-card-bar {
    padding-left: 0;
    .ant-tabs-nav-container {
      .ant-tabs-tab-prev:hover,
      .ant-tabs-tab-next:hover {
        // width: 22px;
        background-color: rgba(0, 0, 0, 0.03);
      }
      font-size: 13px;
      height: 39px;
    }
    .ant-tabs-tab {
      margin-right: 0;
      border-radius: 0px;
      border-top: 0px;
      line-height: 40px;
      .anticon-close {
        display: none;
      }
    }
    .ant-tabs-tab-active {
      padding-bottom: 0px;
      background-color: rgba(0, 0, 0, 0.1);
      .anticon-close {
        display: inline-block;
      }
    }
    .ant-tabs-tab:hover {
      padding-left: 20px;
      padding-right: 20px;
      .anticon-close {
        color: #333;
        display: inline-block;
      }
    }
  }
}

.ant-pro-multi-tab-wrapper {
  .tab_style() !important;
}
</style>
